// @Author EthanScriptOn
// @Desc
package extend_parser

import (
	"encoding/json"
	"fmt"
	"gitee.com/fatzeng/srf_switch_expansion_package/extend_config"
	"gitee.com/fatzeng/srf_switch_stream_bridge/bridge"
	"gitee.com/fatzeng/srf_switch_stream_bridge/framework/actuator"
	"reflect"
)

type RedisQueryResponseParser struct {
}

func (r *RedisQueryResponseParser) Parse(ctx *actuator.SrfSwitchBridgeActuatorContext, config *bridge.BridgeConfig, response interface{}) (interface{}, error) {
	selResults, ok := response.([]*extend_config.RedisQueryOperatorResponse)
	if !ok {
		return nil, fmt.Errorf("response is not []*redis_operator.RedisQueryOperatorResponse")
	}
	dest := reflect.New(config.ResultType)
	if err := r.FetchRecords(ctx, selResults, dest); err != nil {
		return nil, err
	}
	return dest, nil
}

func (r *RedisQueryResponseParser) FetchRecords(ctx *actuator.SrfSwitchBridgeActuatorContext, selResults []*extend_config.RedisQueryOperatorResponse, dest interface{}) (err error) {
	sliceValue := reflect.ValueOf(dest)
	if sliceValue.Kind() != reflect.Ptr || sliceValue.Elem().Kind() != reflect.Slice {
		return fmt.Errorf("dest must be a pointer to a slice")
	}
	elemType := sliceValue.Elem().Type().Elem()
	for _, result := range selResults {
		elem := reflect.New(elemType).Elem()
		if result.Result == "" {
			_ = ctx.Record(actuator.ResultAnalysis, "process redis query result is empty")
			continue
		}
		b := []byte(result.Result)
		err = json.Unmarshal(b, elem.Interface())
		if err != nil {
			return fmt.Errorf("unmarshal result error: %v", err)
		}
		sliceValue.Elem().Set(reflect.Append(sliceValue.Elem(), elem))
	}
	return
}
